package com.freedy.dataStructure.sort;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Random;

/**
 * @author Freedy
 * @date 2021/3/11 14:11
 */
public class Test {
    //测试数组
    public static int[] TEST_ARRAY;
    //最大测试数据
    public static int MAX_TEST_DATA = 80000;
    //是否打印测试数据
    public static boolean whetherPrint = false;
    //是否测试相同数据
    public static boolean whetherSame = false;

    public static void main(String[] args) throws Exception {
        sort("java.util.Arrays");
        sort("com.freedy.dataStructure.sort.ShellSort");
        sort("com.freedy.dataStructure.sort.QuickSort", 0, MAX_TEST_DATA - 1);
        sort("com.freedy.dataStructure.sort.MergeSort", 0, MAX_TEST_DATA - 1, new int[MAX_TEST_DATA]);
        sort("com.freedy.dataStructure.sort.RadixSort");
        sort("com.freedy.dataStructure.sort.BubbleSort");
        sort("com.freedy.dataStructure.sort.SelectSort");
        sort("com.freedy.dataStructure.sort.InsertionSort");
        sort("com.freedy.dataStructure.tree.HeapSort");
    }

    /**
     * 测试主方法
     * 利用反射调取各个类的sort算法
     *
     * @param className 测试类的全类名
     */
    public static void sort(String className, Object... args) {
        try {
            int[] arr = randomArrMaker();
            //通过全类名获取字节码对象
            Class<?> sortClass = Class.forName(className);
            Method[] methods = sortClass.getDeclaredMethods();
            boolean isInvoke = false;
            Exception e = null;
            for (Method method : methods) {
                if (method.getName().equals("sort") &&
                        method.getGenericParameterTypes()[0].
                                getTypeName().equals("int[]")) {
                    method.setAccessible(true);
                    Object[] obj = new Object[args.length + 1];
                    obj[0] = arr;
                    System.arraycopy(args, 0, obj, 1, args.length);
                    //执行方法
                    try {
                        long time = System.currentTimeMillis();
                        method.invoke(null, obj);
                        System.out.println(sortClass.getName() + "总耗时:" + (System.currentTimeMillis() - time));
                        isInvoke = true;
                        break;
                    } catch (Exception exception) {
                        e=exception;
                    }
                }
            }
            if (!isInvoke) {
                if (e!=null){
                    e.printStackTrace();
                }
                throw new RuntimeException("此类中没有符合测试的sort方法,请检查参数是否输入有误.");
            }
            if (whetherPrint) {
                System.out.println(Arrays.toString(arr));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成随机数组
     */
    public static int[] randomArrMaker() {
        Random random = new Random();
        if (whetherSame) {
            if (TEST_ARRAY == null) {
                int[] ints = new int[MAX_TEST_DATA];
                for (int i = 0; i < MAX_TEST_DATA; i++) {
                    ints[i] = random.nextInt(MAX_TEST_DATA * 100);
                }
                TEST_ARRAY = ints;
            }
            return TEST_ARRAY.clone();
        } else {
            int[] ints = new int[MAX_TEST_DATA];
            for (int i = 0; i < MAX_TEST_DATA; i++) {
                ints[i] = random.nextInt(MAX_TEST_DATA * 100);
            }
            return ints;
        }
    }
}

